package com.staginfo.segs.common;

import android.app.Activity;
import android.content.Context;
import android.os.AsyncTask;

import com.staginfo.segs.util.LogUtils;
import com.staginfo.segs.util.Logs;
import com.staginfo.segs.util.SettingUtils;

import org.ksoap2.HeaderProperty;
import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapPrimitive;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransportSE;
import org.ksoap2.transport.ServiceConnectionSE;
import org.xmlpull.v1.XmlPullParserException;

import java.io.IOException;
import java.lang.reflect.Field;
import java.net.SocketTimeoutException;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;


/**
 * 应用配置
 * Created by Administrator on 2016/7/11 0011.
 */
public class Config {
    private static final String TAG = "Config";
    public static final String CONFIG_COOKIE = "Cookie";
    public static final String URL_DEFAULT = "UrlDefault";//默认服务器地址
    public static final String URL_CONFIGURED = "UrlConfigured";//已配置服务器地址
    public static final String USERNAME = "Username";//用户名
    public static final String SAVE_PASSWORD = "savePassword";//是否保存用户名

    public static final boolean isDebugModel = true;//调试模式开启与否,异常捕获、极光调试、程序日志相关，发布时需要置为false
    //以下用于测试模式
    public static final String KEY_TEST_PERMISSION = "KEY_TEST_PERMISSION";//是否有进入测试界面的权限，退出app就取消权限
    public static final String KEY_RADIO_SERVER_SELECT = "KEY_RADIO_SERVER_SELECT";
    public static final String KEY_SERVER_SELECT = "KEY_SERVER_SELECT";
    public static final String KEY_TEST_MODE = "KEY_TEST_MODE";
    public static boolean isTestMode = false;



    public static void setString(Context context, String key, String value) {
        SettingUtils.set(context, key, value);
    }

    public static String getString(Context context, String key, String defaultValue) {
        return SettingUtils.get(context, key, defaultValue);
    }

    public static void setBoolean(Context context, String key, boolean value) {
        SettingUtils.set(context, key, value);
    }

    public static boolean getBoolean(Context context, String key, boolean defaultValue) {
        return SettingUtils.get(context, key, defaultValue);
    }

    public static void setLong(Context context, String key, long value) {
        SettingUtils.set(context, key, value);
    }

    public static long getLong(Context context, String key, long defaultValue) {
        return SettingUtils.get(context, key, defaultValue);
    }

    public static void setInt(Context context, String key, int value) {
        SettingUtils.set(context, key, value);
    }

    public static int getInt(Context context, String key, int defaultValue) {
        return SettingUtils.get(context, key, defaultValue);
    }


    public static boolean isSavePassword(Context context) {
        return SettingUtils.get(context, SAVE_PASSWORD, false);
    }

    public static void setSavePassword(Context context, boolean isSave) {
        SettingUtils.set(context, SAVE_PASSWORD, isSave);
    }



    /**
     * 获取服务器地址,如果未配置，则返回默认地址
     *
     * @param context
     * @return
     */
    public static String getConfiguredServer(Context context) {
        String defaultUrl = SettingUtils.get(context, Config.URL_DEFAULT, Constants.DEFAULT_URL);
//        return SettingUtils.get(context, Config.URL_CONFIGURED, "");
        return SettingUtils.get(context, Config.URL_CONFIGURED, defaultUrl);

    }

    /**
     * 设置服务器地址
     *
     * @param context
     * @param server
     */
    public static void setServer(Context context, String server) {
        SettingUtils.set(context, Config.URL_CONFIGURED, server);
    }

    /**
     * 删除服务器地址
     *
     * @param context
     */
    public static void deleteConfiguredServer(Context context) {
        SettingUtils.remove(context, Config.URL_CONFIGURED);
    }

    /**
     * 设置默认服务器地址
     *
     * @param context
     * @param server
     */
    public static void setDefaultServer(Context context, String server) {
        SettingUtils.set(context, Config.URL_DEFAULT, server);
    }

    /**
     * 获取默认服务器地址
     *
     * @param context
     * @return
     */
    public static String getDefaultServer(Context context) {
        return SettingUtils.get(context, Config.URL_DEFAULT, Constants.DEFAULT_URL);
    }

    /**
     * 获取已保存用户名
     *
     * @param context
     * @return
     */
    public static String getUsername(Context context) {
        LogUtils.d(TAG, "getUsername");
        return SettingUtils.get(context, Config.USERNAME, "");
    }

    /**
     * 保存用户名
     *
     * @param context
     * @param username
     */
    public static void setUsername(Context context, String username) {
        LogUtils.d(TAG, "setUsername");
        SettingUtils.set(context, USERNAME, username);
    }

    public static void deleteUsername(Context context) {
        LogUtils.d(TAG, "deleteUsername");
        SettingUtils.remove(context, USERNAME);
    }

    /**
     * 异步API请求
     * Created by Administrator on 2016/7/7 0007.
     */
    public static class ApiAsyncTask extends AsyncTask<Void,Void,Object> {
        private static final String TAG="ApiAsyncTask";
        //session失效
        public static final int SESSION_INVALID = 700;
        // 超时（网络）异常
        public static final int TIMEOUT_ERROR = 600;
        // 业务异常
        public static final int BUSSINESS_ERROR = 610;
        // 225 请求的数据不存在
        public static final int SC_DATA_NOT_EXIST = 225;
        // 232 非法回复内容
        public static final int SC_ILLEGAL_COMMENT = 232;
        // 421 请求头参数为空或参数不完整（User-Agent等）
        public static final int SC_ILLEGAL_USER_AGENT = 421;
        // 422 请求xml解析错误
        public static final int SC_XML_ERROR = 422;
        // 423 请求xml中参数缺失或参数类型错误
        public static final int SC_XML_PARAMS_ERROR = 423;
        // 427 请求解密或解码错误
        public static final int SC_ENCODE_ERROR = 427;
        //428 没有请求权限
        public static final int DOWNLOAD_STATUS_NOPERMISSION = 428;

        private int requestAction;
        private Object paramter;
        private Context context;
        private String requestUrl;
        private String requestMethod;
        private int waitTime = 10000;
        private boolean isGetCookie=false;//如果为真，则须在头部获取cookie信息,如果为假，则须配置cookie信息
        private ApiRequestListener handler;
        private StermApplication app;

        public ApiAsyncTask(Context context, int requestAction, String requestUrl, String requestMethod, Object paramter, ApiRequestListener handler) {
            this(context, requestAction, requestUrl, requestMethod, paramter, handler, false);
        }
        public ApiAsyncTask(Context context, int requestAction, String requestUrl, String requestMethod, Object paramter, ApiRequestListener handler, boolean isGetCookie) {
            this.context = context;
            this.requestAction = requestAction;
            this.requestUrl = requestUrl;
            this.requestMethod = requestMethod;
            this.paramter = paramter;
            this.handler = handler;
            this.isGetCookie=isGetCookie;
            app = (StermApplication) context.getApplicationContext();
        }
        public ApiAsyncTask(Context context, int requestAction, String requestUrl, String requestMethod, Object paramter, ApiRequestListener handler, int waitTime) {
            this(context, requestAction, requestUrl, requestMethod, paramter, handler, false);
            this.waitTime=waitTime;
        }

        private Object httpPost(){
            Logs.d(TAG,"method:"+requestMethod+":start:"+System.currentTimeMillis());
            SoapObject request=new SoapObject(Constants.WEB_NAMESPACE,requestMethod);

            if(paramter!=null){
                LinkedHashMap<String,String> requestParams= (LinkedHashMap<String, String>) paramter;
                Iterator<Map.Entry<String,String>> paramIterator=requestParams.entrySet().iterator();
                while (paramIterator.hasNext()){
                    Map.Entry<String,String> entry=paramIterator.next();
                    if(entry.getKey()!=null && entry.getValue()!=null){
                        request.addProperty(entry.getKey().toString(),entry.getValue().toString());
                    }
                }
            }
            SoapSerializationEnvelope soapEnvelope=new SoapSerializationEnvelope(SoapEnvelope.VER11);
            soapEnvelope.bodyOut=request;
            soapEnvelope.setOutputSoapObject(request);
            soapEnvelope.dotNet=true;
            HttpTransportSE transport=new HttpTransportSE(requestUrl,waitTime);
            SoapPrimitive response=null;
            try {
                if(isGetCookie){
                    List<HeaderProperty> respHeaders=transport.call("",soapEnvelope,null);
                    for(HeaderProperty hp:respHeaders){
                        String key = hp.getKey();
                        if (key != null){
                            if (key.equals("Set-Cookie")){
                                SettingUtils.set(context, CONFIG_COOKIE,hp.getValue());
                            }
                        }
                    }
                    updateInnerSystemDate(transport);
                }else{
                    List<HeaderProperty> headers=new ArrayList<HeaderProperty>();
                    HeaderProperty hp=new HeaderProperty(CONFIG_COOKIE,SettingUtils.get(context, CONFIG_COOKIE,""));
                    headers.add(hp);
                    transport.call("",soapEnvelope,headers);
                    updateInnerSystemDate(transport);
                }
                response = (SoapPrimitive) soapEnvelope.getResponse();
            } catch (SocketTimeoutException e){
                e.printStackTrace();
                Logs.d(TAG, e.toString());
                return TIMEOUT_ERROR;
            }catch (XmlPullParserException e) {
                e.printStackTrace();
                Logs.d(TAG, e.toString());
                return SC_XML_ERROR;
            }catch (IOException e) {
                e.printStackTrace();
                Logs.d(TAG, e.toString());
                return BUSSINESS_ERROR;
            }
            Logs.d(TAG,response.toString());
            Logs.d(TAG,"method:"+requestMethod+":end s:"+System.currentTimeMillis());
            return response;
        }
        @Override
        protected Object doInBackground(Void... voids) {
            return httpPost();
        }

        @Override
        protected void onPostExecute(Object response) {

            if(handler==null){
                return;
            }
            if(context instanceof Activity && ((Activity)context).isFinishing()){
                return;
            }
            if(response==null){
                handler.onError(this.requestAction,this.BUSSINESS_ERROR);
                return;
            }else if(response instanceof Integer){
                Integer statusCode= (Integer) response;
                if(!handleResult(statusCode)){
                    handler.onError(this.requestAction, (Integer) response);
                    return;
                }
            }else if(response.toString().equals("false")){
                handler.onError(this.requestAction,SC_DATA_NOT_EXIST);
                return;
            }else if(response.toString().equals("noPermission")){
                handler.onError(this.requestAction,DOWNLOAD_STATUS_NOPERMISSION);
                return;
            }else if(response.toString().equals("Session Invalid")){
                handler.onError(this.requestAction,SESSION_INVALID);
                return;
            }

            handler.onSuccess(this.requestAction,response);
        }

        /**
         *
         * true则表示已被服务器正常接收
         * @param statusCode
         * @return
         */
        private boolean handleResult(int statusCode){
            return statusCode==200;
        }

        private void updateInnerSystemDate(HttpTransportSE transport){
            ServiceConnectionSE connectionSE = (ServiceConnectionSE) transport.getConnection();
            Class userCla = (Class) connectionSE.getClass();
            Field[] fields = userCla.getDeclaredFields();
            URLConnection connection = null;
            try {
                for(Field field : fields){
                    if (field.getName().equals("connection")){
                        field.setAccessible(true);
                        connection = (URLConnection) field.get(connectionSE);
                        break;
                    }
                }
            }catch (IllegalAccessException e){
                Logs.d("zxc", "error   "+e.toString());
            }
            if (connection!=null){
                long t = connection.getDate();
                Logs.d("zxc", "net date "+ t + new Date(t).toString());
    //            app.setInnerSystemTime(connection.getDate());
            }
        }

        /**
         * 服务器请求回调
         */
        public interface ApiRequestListener{
            void onSuccess(int method, Object obj);
            void onError(int method, int statusCode);
        }
    }
}
